﻿@using StackExchange.Opserver.Data.SQL
@model SQLNode.AvailabilityGroupInfo
@{
    var ag = Model;
    if (!ag.HasDatabases)
    {
        // don't render empty AGs
        return;
    }
}
@helper RenderDBIssues(SQLNode.AvailabilityGroupReplicaInfo r) {
    if (r.SynchronizationHealth != SynchronizationHealths.Healthy)
    {
        var unhealthy = r.Databases.Where(db => db.SynchronizationHealth.HasValue && db.SynchronizationHealth != SynchronizationHealths.Healthy);
        if (r.Databases.Count > unhealthy.Count())
        {
            foreach (var db in unhealthy.OrderBy(u => u.DatabaseName))
            {
                <div class="ag-db-error" title="@db.DatabaseName
Sync: @(db.SynchronizationState.HasValue ? db.SynchronizationState.Value.GetDescription() : "Unknown")
Health: @(db.SynchronizationHealth.HasValue ? db.SynchronizationHealth.Value.GetDescription() : "Unknown")
@if (db.SuspendReason.HasValue) {<text>
Suspension Reason: @db.SuspendReason.GetDescription()</text>}">@db.IconSpan() @db.MonitorStatus.Span(db.DatabaseName)</div>
            }
        }
        else
        {
            <div class="ag-error">Sync: @r.SynchronizationHealth.GetDescription()</div>
        }
    }
}
<div class="ag-wrap">
                <div class="ag-inner@(ag.MonitorStatus == MonitorStatus.Good ? "" : " ag-problem")">
                    <div class="header"><span class="cluster-name">@ag.IconSpan() @ag.Node.Cluster.Name:</span> <a href="#/cluster/@ag.Node.Cluster.Name.UrlEncode()/@ag.Name.UrlEncode()">@ag.Name</a></div>
                    <div class="ag-node ag-primary">
                        <div class="ag-name">
                            <span class="ag-node-name">@ag.LocalReplica.IconSpan() <a href="#/cluster/@ag.Node.Cluster.Name.UrlEncode()/@ag.Name.UrlEncode()/@ag.Node.Name.UrlEncode()">@ag.Node.Name</a></span>
                        </div>
                        <div class="ag-databases">
                            <span class="icon database status-up"></span> @SQLHelpers.HealthDescriptionAGs(ag.LocalReplica.ReplicaNode, ag.LocalReplica.Databases, minimal: true)
                        </div>
                        @RenderDBIssues(ag.LocalReplica)
                        <div class="ag-transfer">
                            <span class="icon arrow up"></span>@(((long)ag.RemoteReplicas.Sum(r => r.BytesSentPerSecond)).ToSize(zero: "0")) <span class="note">/sec</span>
                            <span class="icon arrow down"></span>@(((long)ag.RemoteReplicas.Sum(r => r.BytesReceivedPerSecond)).ToSize(zero: "0")) <span class="note">/sec</span>
                        </div>
                        <div class="ag-queue">
                            <span class="label">Log Size:</span> @ag.LocalReplica.Databases.Sum(db => db.LogKBytesUsed).ToComma() <span class="note">kB</span>
                            <div class="ag-poll">@ag.Node.LastFetch.ToPollSpan(mini: true, lastSuccess: true)</div>
                        </div>
                        @if (ag.GroupSynchronizationHealth != SynchronizationHealths.Healthy && ag.LocalReplica != null)
                        {
                            var volumeIds = ag.Node.Databases.SafeData(true).Where(db => ag.LocalReplica.Databases.Select(rdb => rdb.DatabaseId).Contains(db.Id)).Select(db => db.LogVolumeId);
                            var volumes = ag.Node.Volumes.SafeData(true).Where(v => volumeIds.Contains(v.VolumeId));
                            foreach(var v in volumes)
                            {
                            <div class="ag-log-volume">
                                <span class="label">Space Free:</span> @v.VolumeMountPoint 
                                <span class="volume-space">@((v.AvailableBytes / 1024).ToComma()) <span class="note">kB</span></span>
                            </div>
                            }
                        }
                    </div>
                    @foreach (var r in ag.RemoteReplicas)
                    {
                        <div class="ag-node ag-replica@(r.SynchronizationHealth == SynchronizationHealths.Healthy ? "" : " ag-problem")" title="Group: @r.AvailabilityGroupName
    Node: @r.ReplicaServerName
    ReplicaId: @r.ReplicaId
    Sync Health: @r.SynchronizationHealth
    Connection State: @r.ConnectedState
    Mode: @r.AvailabilityMode">
                            <div class="ag-name">
                                <span class="ag-node-name">
                                    @r.IconSpan() <a href="#/cluster/@ag.Node.Cluster.Name.UrlEncode()/@ag.Name.UrlEncode()/@r.ReplicaServerName.UrlEncode()">@r.ReplicaServerName</a>
                                    @switch (r.AvailabilityMode)
                                    {
                                        case AvailabilityModes.AsyncrhonousCommit: <span class="note">(async)</span>
                                            break;
                                        case AvailabilityModes.SynchronousCommit: <span class="note bold">(sync)</span>
                                            break;
                                        default: <span class="note warning">(unknown)</span>
                                            break;
                                    }
                                </span>
                            </div>
                            <div class="ag-databases">
                                <span class="icon database status-up"></span> @SQLHelpers.HealthDescriptionAGs(r.ReplicaNode, r.Databases, minimal: true)
                            </div>
                            @RenderDBIssues(r)
                            <div class="ag-transfer">
                                <span class="icon arrow up"></span> @(((long)r.BytesReceivedPerSecond).ToSize(zero: "0")) <span class="note">/sec</span>
                                <span class="icon arrow down"></span> @(((long)r.BytesSentPerSecond).ToSize(zero: "0")) <span class="note">/sec</span>
                            </div>
                            <div class="ag-queue">
                                <span class="label">Queue:</span> @r.Databases.Sum(db => db.LogSendQueueSize).ToComma() <span class="note">kB</span>
                                <div class="ag-poll">@ag.Node.LastFetch.ToPollSpan(mini: true, lastSuccess: true)</div>
                            </div>
                        </div>
                    }
                </div>
            </div>